//
//  XS_OnDemand.swift
//  Alamofire
//
//  Created by 韩云智 on 2020/7/23.
//

import UIKit
import RxSwift
import RxCocoa

public enum XS_OnDemandError: Error {
    case weakError
}

open class XS_OnDemand: NSObject {
    private lazy var disposeBag = DisposeBag()
    open var resourceRequest: NSBundleResourceRequest!
    
    public init(_ tags: Set<String>, loadingPriority: Double = 0.5, priority: Double = 0) {
        Bundle.main.setPreservationPriority(priority, forTags: tags)
        resourceRequest = NSBundleResourceRequest(tags: tags)
        resourceRequest.loadingPriority = loadingPriority
    }

    open func accessingResources(_ activity: Bool = false, completionHandler: @escaping (Error?)->Void) {
        resourceRequest.conditionallyBeginAccessingResources { [weak self] resourcesAvailable in
            if resourcesAvailable {
                DispatchQueue.main.async { completionHandler(nil) }
            } else {
                guard let `self` = self else {
                    DispatchQueue.main.async { completionHandler(XS_OnDemandError.weakError) }
                    return
                }
                DispatchQueue.main.async { if activity { showActivity(true) } }
                self.resourceRequest.beginAccessingResources { err in
                    DispatchQueue.main.async {
                        if activity { hideActivity() }
                        completionHandler(err)
                    }
                }
            }
        }
    }
    open func endAccessingResources() {
        resourceRequest.endAccessingResources()
    }
    
    open func trackTheProgress(_ completionHandler: @escaping (Double?)->Void) {
        resourceRequest.progress.rx.observeWeakly(Double.self, "fractionCompleted")
            .asDriver(onErrorJustReturn: nil)
            .drive(onNext: { [weak self] progress in
                completionHandler(progress)
                if progress == nil || progress == 1 {
                    self?.disposeBag = DisposeBag()
                }
            }).disposed(by: disposeBag)
    }
}
